package com.woniuxy.service;

import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSBuckets;
import com.mongodb.client.gridfs.GridFSDownloadStream;
import com.mongodb.client.gridfs.model.GridFSFile;
import com.woniuxy.dto.GridFileDto;
import com.woniuxy.utils.IOUtil;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

@Service
public class GridFileService {
    @Autowired
    private GridFsTemplate gridFsTemplate;
    @Autowired
    private MongoDatabaseFactory mongoDatabaseFactory;


    public GridFileDto get(String id) throws IOException {
        GridFileDto fileDto = new GridFileDto();

        Query query = Query.query(Criteria.where("_id").is(new ObjectId(id)));
        GridFSFile gridFsFile = this.gridFsTemplate.findOne(query);
        fileDto.setFileName(gridFsFile.getFilename());
        fileDto.setFileContentType(gridFsFile.getMetadata().getString("_contentType"));

        GridFSBucket gridFSBucket = GridFSBuckets.create(mongoDatabaseFactory.getMongoDatabase());


        try(GridFSDownloadStream gridFSDownloadStream = gridFSBucket.openDownloadStream(gridFsFile.getObjectId())){
            GridFsResource gridFsResource = new GridFsResource(gridFsFile, gridFSDownloadStream);
            try( InputStream inputStream = gridFsResource.getInputStream()){
                fileDto.setFileContent(IOUtil.toByteArray(inputStream));
            }
        }
        return fileDto;
    }
    @Transactional(rollbackFor = Exception.class,transactionManager = "mongoTransactionManager")
    public void save(GridFileDto dto){
        InputStream is = new ByteArrayInputStream(dto.getFileContent());
        ObjectId objectId = this.gridFsTemplate.store(is, dto.getFileName(), dto.getFileContentType(), dto.getMetadata());
        dto.setId(objectId.toString());
    }

    @Transactional(rollbackFor = Exception.class,transactionManager = "mongoTransactionManager")
    public void saveAll(List<GridFileDto> dtos){
        for (GridFileDto dto : dtos) {
            this.save(dto);
        }
    }
}
